package cn.autumnorange.app.common.consumer.rpc;

import cn.autumnorange.app.common.consumer.rpc.header.wrapper.HttpServletRequestRPCWrapper;
import cn.autumnorange.app.common.rpc.RPCIDHeaderStrategy;
import cn.autumnorange.app.common.rpc.RPCWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class ConsumerRPCServiceImpl implements ConsumerRPCService {
  @Value("${ribbon.ConnectTimeout}")
  private long connectTimeout;

  @Value("${ribbon.ReadTimeout}")
  private long readTimeout;

  @Value("${ribbon.MaxAutoRetries}")
  private int maxAutoRetries;

  @Value("${ribbon.MaxAutoRetriesNextServer}")
  private int maxAutoRetriesNextServer;

  @Override
  public void setConsumerReadTimeoutToHeader(String rpcId) {
    if (StringUtils.isNotBlank(rpcId)) {
      ((HttpServletRequestRPCWrapper) RPCWrapper.getHttpServletRequestRPCWrapper())
          .setHeader(ConsumerRPCService.CONSUMERREADTIMEOUT, String.valueOf(readTimeout));
    }
  }

  // 机器调用时间物理损耗
  @Override
  public void setRPCLockTimeToHeader(String rpcId) {
    //    总调用次数应该这样算
    //    int rpcTotal = maxAutoRetries + 1 + maxAutoRetriesNextServer * (maxAutoRetries + 1);

    //    connectTimeout这里是连接到下一个服务实例需要的时间
    //    锁住的时间必须到下一个服务连接成功并开始执行获得锁的代码 未到具体处理代码块前执行代码消耗的时间MORERPCTIMEOUT
    if (StringUtils.isNotBlank(rpcId)) {
      long rpcLockTime = connectTimeout + readTimeout + ConsumerRPCService.MORERPCTIMEOUT;
      log.debug("set rpc幂等接口每次调用锁住的时间大于一次调用的readTimeOut时间:" + rpcLockTime);
      ((HttpServletRequestRPCWrapper) RPCWrapper.getHttpServletRequestRPCWrapper())
          .setHeader(ConsumerRPCService.RPCLOCKTIME, String.valueOf(rpcLockTime));
    }
  }

  @Override
  public void setRPCId(String rpcId) {
    ((HttpServletRequestRPCWrapper) RPCWrapper.getHttpServletRequestRPCWrapper())
            .setHeader(ConsumerRPCService.RPCID, rpcId);
  }

  @Override
  public String getRPCId() {
//    return ((HttpServletRequestRPCWrapper) RPCWrapper.getHttpServletRequestRPCWrapper())
//            .getHeader(ConsumerRPCService.RPCID);
    return RPCWrapper.getHttpServletRequestRPCWrapper().getHeader(RPCIDHeaderStrategy.RPCID);

  }

  @Override
  public String getConsumerReadTimeoutToHeader() {
    return ((HttpServletRequestRPCWrapper) RPCWrapper.getHttpServletRequestRPCWrapper())
            .getHeader(ConsumerRPCService.CONSUMERREADTIMEOUT);
  }

  @Override
  public String getRPCLockTimeToHeader() {
    return ((HttpServletRequestRPCWrapper) RPCWrapper.getHttpServletRequestRPCWrapper())
            .getHeader(ConsumerRPCService.RPCLOCKTIME);
  }


}
